#include <cstring>
#include "Instruction.h"
namespace s2e {
namespace plugins {

Instruction::Instruction() {
	this->size = 0;
	std::memset(this->opcode, 0x00, sizeof(this->opcode));
}

Instruction::Instruction(const s2e::uint8 *opcode, s2e::uint32 opSize) :
		Instruction::Instruction() {
	this->setOpcode(opcode, opSize);
}

Instruction::Instruction(const Instruction &other) {
	this->copy(other);
}

Instruction& Instruction::operator=(const Instruction &other) {
	this->copy(other);
	return *this;
}

void Instruction::copy(const Instruction &other) {
	this->address = other.address;
	this->size = other.size;
	std::memcpy(this->opcode, other.opcode, sizeof(this->opcode));
}
void Instruction::setOpcode(const s2e::uint8 *opcode, s2e::uint32 size) {
	if (size >= sizeof(this->opcode))
		size = sizeof(this->opcode);
	std::memcpy(this->opcode, opcode, size);
	this->size = size;
}

const s2e::uint8* Instruction::getOpcode(void) const {
	return this->opcode;
}

s2e::uint32 Instruction::getSize(void) const {
	return this->size;
}
s2e::uint64 Instruction::getAddress(void) const {
	return this->address;
}

Instruction::~Instruction() {

}
std::ostream& operator<<(std::ostream &stream, const Instruction &inst) {
	for (int i = 0; i < inst.size; i++) {
		stream << "\\x" << std::hex << std::setw(2) << std::setfill('0')
				<< (unsigned) inst.opcode[i];
	}
	stream << std::dec;
	return stream;
}

std::ostream& operator<<(std::ostream &stream, const Instruction *inst) {
	stream << *inst;
	return stream;
}
}
}
